home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks97
/
VerticalHold.sit
/
Vertical Hold
/
source code
/
Bzzt.cpp
next >
Wrap
C/C++ Source or Header
|
1997-06-27
|
8KB
|
370 lines
#include <LowMem.h>
#include <A4Stuff.h>
#include <QuickDraw.h>
#include <Memory.h>
#include <Resources.h>
#include <Fonts.h>
#include <Dialogs.h>
#include <QDOffscreen.h>
#include <string.h>
#include <stdio.h>
#include <Timer.h>
#define SIMPLE 0
#define PreserveFlags(x, y) ((x & 0xC000) | (y & 0x3FFF))
#define crsrBase 0x898
enum {
uppA5Info = kCStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))
};
enum {
uppMyProcInfo = kPascalStackBased
};
unsigned long __procinfo = uppMyProcInfo;
typedef struct {
TMTask task;
Ptr mainBaseAddr;
Size worldBytes;
Ptr worldBuffer;
short rowBytes;
short phase;
Rect size;
short offset;
} MyTaskRec;
#define kUpdateSpeed 90
typedef struct {
short numPorts;
GrafPtr ports [1];
} **PortListHdl;
int currentPlug = 0;
static bool Bypass ()
{
char* t = (char*)0x17b;
char* t2 = (char*) 0x183;
if(*t2 & 4)
currentPlug = 0;
if(*t2 & 1)
currentPlug = 1;
t2 = (char *) 0x180;
if(*t2 & 8)
currentPlug = 2;
if(*t2 & 1)
currentPlug = 4;
if(*t2 & 2)
currentPlug = 5;
if(*t2 & 4)
currentPlug = 6;
if(*t2 & 16)
currentPlug = 7;
if(*t2 & 32)
currentPlug = 8;
t2 = (char *) 0x182;
if(*t2 & 0x40)
currentPlug = 3;
if (*t & 2)
return true;
else
return false;
}
void doWavePlug(MyTaskRec* myTask);
void doScrollerPlug(MyTaskRec* myTask);
void doFallingDoorPlug(MyTaskRec* myTask);
void doKaliedPlug(MyTaskRec* myTask);
void doSlidePlug(MyTaskRec* myTask);
void doMungePlug(MyTaskRec* myTask);
void doPixelatorPlug(MyTaskRec* myTask);
void doInvertPlug(MyTaskRec* myTask);
void doSnowPlug(MyTaskRec* myTask);
static
void ChangeAllPorts (Ptr oldBaseAddr, Ptr newBaseAddr)
{
PortListHdl ports = *((PortListHdl*) 0x0000d66);
for (int i = 0; i < (**ports).numPorts; ++i) {
if ((**ports).ports [i] -> portBits.rowBytes & 0xC000) {
CGrafPtr port = (CGrafPtr) ((**ports).ports [i]);
if (GetPixBaseAddr (port -> portPixMap) == oldBaseAddr)
(**(port -> portPixMap)).baseAddr = newBaseAddr;
} else {
GrafPtr port = ((**ports).ports [i]);
if (port -> portBits.baseAddr == oldBaseAddr)
port -> portBits.baseAddr = newBaseAddr;
}
}
}
static
pascal void SimpleBlit (MyTaskRec* myTask)
{
short height = myTask -> size.bottom - myTask -> size.top;
short phase = myTask -> phase;
short rowBytes = myTask -> rowBytes;
Ptr worldBuffer = myTask -> worldBuffer;
Ptr screenBuffer = myTask -> mainBaseAddr;
BlockMoveDataUncached (worldBuffer, screenBuffer, height * rowBytes);
}
static void FancyBlit (MyTaskRec* myTask)
{
short height = myTask -> size.bottom - myTask -> size.top;
short phase = myTask -> phase;
short rowBytes = myTask -> rowBytes;
Ptr worldBuffer = myTask -> worldBuffer;
Ptr screenBuffer = myTask -> mainBaseAddr;
BlockMoveDataUncached (worldBuffer + phase * rowBytes, screenBuffer, (height - phase) * rowBytes);
BlockMoveDataUncached (worldBuffer, screenBuffer + (height - phase) * rowBytes, phase * rowBytes);
phase += myTask -> offset;
if (phase >= height)
phase = 0;
else if (phase < 0)
phase = height;
myTask -> phase = phase;
}
void doWavePlug(MyTaskRec* myTask);
void doScrollerPlug(MyTaskRec* myTask);
void doFallingDoorPlug(MyTaskRec* myTask);
void doKaliedPlug(MyTaskRec* myTask);
pascal void MyCTimerProc (MyTaskRec* myTask);
/*
static asm void MyTimerProc ()
{
move.l a1, -(sp)
jsr MyCTimerProc
rts
}
*/
typedef struct {
QDGlobals qd; // Storage for the QuickDraw globals
long qdGlobalsPtr; // A5 points to this place; it will contain a pointer to qd
} QDStorage;
MyTaskRec myTask;
static long MySetA5 (void* value)
{
short hex [7] = {
0x4e56,
0x0000,
0x202e,
0x0008,
0xc18d,
0x4e5e,
0x4e75
};
MakeDataExecutable (&hex, 14);
UniversalProcPtr upp = NewRoutineDescriptor ((ProcPtr) &hex, uppA5Info, kM68kISA);
if (!upp)
DebugStr ("\pDONT EVEN THINK ABOUT IT!");
long oldA5 = CallUniversalProc (upp, uppA5Info, value);
return oldA5;
}
pascal void MyCTimerProc (MyTaskRec* myTask)
{
EnterCodeResource ();
if (Bypass ())
{
switch(currentPlug)
{
case 0:
doMungePlug(myTask);
break;
case 1:
FancyBlit (myTask);
break;
case 2:
doInvertPlug(myTask);
break;
case 3:
doScrollerPlug(myTask);
break;
case 4:
doSlidePlug (myTask);
break;
case 5:
doFallingDoorPlug(myTask);
break;
case 6:
doPixelatorPlug(myTask);
break;
case 7:
doKaliedPlug(myTask);
break;
case 8:
doWavePlug(myTask);
break;
}
}
else
SimpleBlit (myTask);
ExitCodeResource ();
PrimeTime ((QElemPtr) myTask, kUpdateSpeed);
}
static void Override ()
{
long oldA5; // Original value of register A5
QDStorage qds; // Fake QD globals
oldA5 = MySetA5(&qds.qdGlobalsPtr); // Tell A5 to point to the end of the fake QD Globals
InitGraf(&qds.qd.thePort); // Initialize the fake QD Globals
GDHandle mainDevice = GetMainDevice ();
PixMapHandle mainPixMap = (**mainDevice).gdPMap;
Rect mainBounds = (**mainDevice).gdRect;
short mainRowBytes = (**(**mainDevice).gdPMap).rowBytes;
myTask.mainBaseAddr = (**(**mainDevice).gdPMap).baseAddr;
myTask.phase = 0;
GWorldPtr world = nil;
Rect tempBounds = mainBounds;
tempBounds.bottom = tempBounds.top + 1;
if (NewGWorld (&world, (**mainPixMap).pixelSize, &tempBounds, nil, nil, 0))
goto Exit;
GDHandle device = GetGWorldDevice (world);
PixMapHandle worldPixMap = GetGWorldPixMap (world);
// GWorld is really short, make a new buffer for it
Ptr oldWorldBuffer = (**worldPixMap).baseAddr;
short oldWorldRowBytes = (**worldPixMap).rowBytes;
long bytesNeeded = (mainBounds.bottom - mainBounds.top) * (mainRowBytes & 0x3FFF);
Ptr newWorldBuffer = NewPtrSys (bytesNeeded);
if (!newWorldBuffer)
goto Exit;
LockPixels (worldPixMap);
(**worldPixMap).baseAddr = newWorldBuffer;
(**worldPixMap).rowBytes = mainRowBytes;
(**worldPixMap).bounds = mainBounds;
LockPixels (mainPixMap);
short worldRowBytes = (**worldPixMap).rowBytes;
myTask.worldBytes = (mainBounds.bottom - mainBounds.top) * (worldRowBytes & 0x3FFF);
myTask.worldBuffer = GetPixBaseAddr (worldPixMap);
myTask.rowBytes = worldRowBytes & 0x3FFF;
myTask.size = mainBounds;
*((Ptr*)crsrBase) = myTask.worldBuffer;
(**(**mainDevice).gdPMap).baseAddr = myTask.worldBuffer;
GDeviceChanged (mainDevice);
GrafPtr wMgrPort;
GetWMgrPort (&wMgrPort);
short wMgrRowBytes = wMgrPort -> portBits.rowBytes;
wMgrPort -> portBits.baseAddr = myTask.worldBuffer;
CGrafPtr cwMgrPort;
GetCWMgrPort (&cwMgrPort);
short cwMgrRowBytes = (**(cwMgrPort -> portPixMap)).rowBytes;
(**cwMgrPort -> portPixMap).baseAddr = myTask.worldBuffer;
LMSetScrnBase (myTask.worldBuffer);
ChangeAllPorts (myTask.mainBaseAddr, myTask.worldBuffer);
BlockMoveDataUncached (myTask.mainBaseAddr, myTask.worldBuffer, myTask.worldBytes);
myTask.task.tmAddr = (TimerUPP) NewTimerProc (MyCTimerProc);
myTask.task.tmCount = 0;
myTask.task.tmWakeUp = 0;
myTask.task.tmReserved = 0;
myTask.offset = -5;
MySetA5((void*)oldA5);
InsXTime ((QElemPtr) &myTask);
PrimeTime ((QElemPtr) &myTask, 300);
return;
Exit:
DebugStr ("\pError");
}
void initWavePlug();
extern "C" {
pascal
void main ();
}
pascal
void main ()
{
EnterCodeResource ();
THz oldZone = GetZone ();
SetZone (SystemZone ());
Handle me = Get1IndResource ('INIT', 1);
HLock (me);
if (!me)
goto Exit;
initWavePlug();
Override ();
DetachResource (me);
Exit:
SetZone (oldZone);
ExitCodeResource ();
}